/*!
 * 文件名称： driver_public.c
 * 描    述： public 驱动文件
 * 版本：     2023-12-03, V1.0
*/

/*
* GD32F303东方红开发板V1.0
* 淘宝商城：   https://juwo.taobao.com
* 技术交流：   https://www.gd32bbs.com/ask/
* 视频学习：   https://space.bilibili.com/475462605
* 微信公众号： gd32bbs
* Copyright    苏州聚沃电子科技有限公司
* 版权所有，盗版必究。
*/

#include "driver_public.h"
 

typdef_tick_handle driver_tick_handle[]=
{
    {
        .tick_value=1,
        .tick_task_callback=NULL
    },
    {
        .tick_value=10,
        .tick_task_callback=NULL
    },
    {
        .tick_value=100,
        .tick_task_callback=NULL,
    }
};

#define TICK_HANDLE_SIZE  sizeof(driver_tick_handle)/sizeof(typdef_tick_handle)

volatile uint64_t driver_tick=0;
static uint32_t delay_us_mul=0; 

/*!
* 说明     systic初始化（默认1ms）
* 输入[1]  无
* 返回值   无
*/
static void systick_config(void)
{          
    SystemCoreClockUpdate();
    /* setup systick timer for 1000Hz interrupts */
    if (SysTick_Config(SystemCoreClock / 1000U)){
        /* capture error */
        while (1){
        }
    }
    /* configure the systick handler priority */
    NVIC_SetPriority(SysTick_IRQn, 0xFU);
}

/*!
* 说明     driver相关公共驱动初始化
* 输入[1]  无
* 返回值   无
*/
void driver_init(void)
{
    rcu_periph_clock_enable(RCU_AF);
    gpio_pin_remap_config(GPIO_SWJ_SWDPENABLE_REMAP, ENABLE);
    
    systick_config();
    delay_us_mul=SystemCoreClock/1000000; 

    #if (LCD_DEBUG == 1)
//    #include "bsp_lcd.h"      
    bsp_lcd_init();                 /* 初始化LCD */
    bsp_lcd_clear(WHITE);
    //显示log图片
    bsp_show_log();    
    //设置打印窗口
    bsp_lcd_printf_init(10,109,bsp_lcd_parameter.width-1,bsp_lcd_parameter.height-1,FONT_ASCII_16_8,WHITE,BLUE);    
    #endif    
}

/*!
* 说明     1us延时
* 输入[1]  count：us单位
* 返回值   无
*/
void delay_us(uint32_t count)
{
    uint32_t temp;
    SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
                     SysTick_CTRL_TICKINT_Msk   |
                     SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */
    count=count*delay_us_mul;

    if(count>SysTick->LOAD ){
        count=SysTick->LOAD ;
    }
    temp=SysTick->VAL;
    if(temp>count)
    {
        while(SysTick->VAL>(temp-count) && SysTick->VAL<=temp);
    }
    else {
        while(SysTick->VAL<=temp);
        while(SysTick->VAL>(SysTick->LOAD-(count-temp)));        
    }
}

/*!
* 说明     机器周期延时
* 输入[1]  count：机器周期个数
* 返回值   无
*/
void delay_sysclk(uint32_t count)
{
    uint32_t temp;
    SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
                     SysTick_CTRL_TICKINT_Msk   |
                     SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */   
    if(count>SysTick->LOAD ){
        count=SysTick->LOAD ;
    }
    temp=SysTick->VAL;
    if(temp>count)
    {
        while(SysTick->VAL>(temp-count) && SysTick->VAL<=temp);
    }
    else {
        while(SysTick->VAL<=temp);
        while(SysTick->VAL>(SysTick->LOAD-(count-temp)));        
    }
}

/*!
* 说明     1ms延时
* 输入[1]  count：ma单位
* 返回值   无
*/
void delay_ms(uint32_t count)
{  
    count=count*10;
    do{
        delay_us(100);
    }while(count--);
}

/*!
* 说明     1ms tick递增函数，在systic中断调用
* 输入[1]  无
* 返回值   无
*/
void driver_tic_inc(void)
{
    driver_tick++;
    for(uint8_t i=0;i<TICK_HANDLE_SIZE;i++)
    {
        if(driver_tick % driver_tick_handle[i].tick_value ==0 &&  driver_tick_handle[i].tick_task_callback!=NULL)
        {
            driver_tick_handle[i].tick_task_callback();    
        }
    }
}


//void printf_log(const char * sFormat, ...)
//{
////    printf("*");
//    printf("%s",sFormat);
////    printf("/r/n");
//    #ifdef LCD_DEBUG
////    #include "bsp_lcd.h" 
////    extern void bsp_lcd_printf(const char * sFormat, ...);
////    bsp_lcd_printf("*");
//    bsp_lcd_printf("%s",sFormat);
////    bsp_lcd_printf("/r/n");
//    #endif
//}

/*!
    \brief      memory compare function
    \param[in]  src: source data pointer
    \param[in]  dst: destination data pointer
    \param[in]  length: the compare data length
    \param[out] none
    \retval     ErrStatus: ERROR or SUCCESS
*/
Drv_Err memory_compare(uint8_t* src, uint8_t* dst, uint16_t length) 
{
    while(length --){
        if(*src++ != *dst++)
            return DRV_ERROR;
    }
    return DRV_SUCCESS;
}

